﻿using NetSDKCS;
using PSDClient.Service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.XPath;
using CaseManagerLibrary.Models;
using PSDLib.Models;
using PSDLib;
using PSDLib.Ctrl;

namespace PSDClient
{
    // public delegate void UpdateCtl_TreeView(object data);
    public delegate void UpdateTaskTree(dl_task task, List<dl_task_channel> channels);
    public delegate void UpdateDownloadState(string id, int state);
    public delegate void UpdateCtl_Downlader(dl_files file);
    public delegate HResult CreateDownloader(dl_files file);
    public delegate void UpdateDownloader(dl_files file, int time);
    public delegate void FinishDownload(dl_files file);
    public delegate void SetDeviceInfo(dl_download_device device);

    public partial class FrmMain : Form
    {
        bool running = false;
        bool stop_manual = false;
        //private UpdateCtl_TreeView updateCtlTreeView_Clear;
        //private UpdateCtl_TreeView updateCtlTreeView_Task;
        //private UpdateCtl_TreeView updateCtlTreeView_Channel;

        //private UpdateCtl_TreeView updateCtlTreeView_TaskState;
        //private UpdateCtl_TreeView updateCtlTreeView_ChannelState;

        //private CreateDownloader createDownloader;
        private UpdateTaskTree updateTaskTree;
        private UpdateDownloadState updateTaskDownloadState;
        private UpdateDownloadState updateChannelDownloadState;
        private UpdateDownloader updateDownloader;
        private SetDeviceInfo setDeviceInfo;

        private FinishDownload finishDownload;

        private DownloadHelper downloadHelper;
        public FrmMain()
        {
            InitializeComponent();

            this.WindowState = FormWindowState.Maximized;

            this.palDownloadList.BackColor = Color.FromArgb(238, 249, 255);

            downloadHelper = new DownloadHelper();
            downloadHelper.PSDClient = this.psdClient;
            this.psdClient.DownloadHelper = downloadHelper;
            downloadHelper.OnCreateTask += DownloadHelper_OnCreateTask1;
            downloadHelper.OnStartDownload += DownloadHelper_OnStartDownload;
            downloadHelper.OnStopDownload += DownloadHelper_OnStopDownload;
            downloadHelper.OnCreateDownload += DownloadHelper_OnCreateDownload;
            downloadHelper.OnFileDownloadSuccess += DownloadHelper_OnFileDownloadSuccess;
            downloadHelper.OnFileDownloadFail += DownloadHelper_OnFileDownloadFail;
            downloadHelper.OnUpdateDownloadProgress += DownloadHelper_OnUpdateDownloadProgress;
            downloadHelper.OnDownloadTaskStateChanged += DownloadHelper_OnDownloadTaskStateChanged;
            downloadHelper.OnDownloadChannelStateChanged += DownloadHelper_OnDownloadChannelStateChanged;
            downloadHelper.OnSetDeviceInfo += DownloadHelper_OnSetDeviceInfo;

            SetUIEventHandler();

            this.Shown += FrmMain_Shown;
            this.FormClosing += FrmMain_FormClosing;
        }



        private void SetUIEventHandler()
        {
            #region 设置UI委托

            updateTaskTree = new UpdateTaskTree(delegate (dl_task task, List<dl_task_channel> channels)
            {
                try
                {
                    var node = this.tvwTask.Nodes.Find(task.id, false);
                    TreeNode node_task = null;

                    if (node.Length == 0)
                    {
                        node_task = new TreeNode();
                        tvwTask.Nodes.Add(node_task);
                    }
                    else
                    {
                        node_task = node[0];
                    }

                    node_task.Text = CreateTaskNodeText(task);
                    node_task.Tag = task;
                    node_task.Name = task.id;
                    node_task.ImageIndex = task.download_state;
                    node_task.SelectedImageIndex = task.download_state;

                    node_task.Nodes.Clear();

                    foreach (var ch in channels)
                    {
                        var node_ch = new TreeNode();
                        node_ch.Text = CreateChannelNodeText(ch);
                        node_ch.Tag = ch;
                        node_ch.ImageIndex = ch.download_state + 3;
                        node_ch.SelectedImageIndex = ch.download_state + 3;
                        node_ch.Name = ch.id;

                        node_task.Nodes.Add(node_ch);
                    }

                    node_task.ExpandAll();
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " updateTaskTree " + s);

                }
            });

            updateTaskDownloadState = new UpdateDownloadState(delegate (string id, int state)
            {
                try
                {
                    var node_task = tvwTask.Nodes.Find(id, false);
                    if (node_task.Length > 0)
                    {
                        var task = node_task[0].Tag as dl_task;
                        task.download_state = state;

                        if (state == 2)
                        {
                            node_task[0].Remove();
                        }
                        else
                        {
                            node_task[0].Text = CreateTaskNodeText(task);
                            node_task[0].ImageIndex = state;
                            node_task[0].SelectedImageIndex = state;

                            foreach (TreeNode node_ch in node_task[0].Nodes)
                            {
                                var ch = (node_ch.Tag as dl_task_channel);
                                if (ch.download_state < 2)
                                {
                                    ch.download_state = state;

                                    node_ch.Text = CreateChannelNodeText(ch);
                                    node_ch.ImageIndex = state + 3;
                                    node_ch.SelectedImageIndex = state + 3;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " updateTaskDownloadState " + s);

                }
            });

            updateChannelDownloadState = new UpdateDownloadState(delegate (string id, int state)
            {
                try
                {
                    var node_ch = tvwTask.Nodes.Find(id, true);
                    if (node_ch.Length > 0)
                    {
                        var ch = (node_ch[0].Tag as dl_task_channel);
                        if (ch.download_state < 2)
                        {
                            ch.download_state = state;
                        }

                        node_ch[0].Text = CreateChannelNodeText(ch);
                        node_ch[0].ImageIndex = state + 3;
                        node_ch[0].SelectedImageIndex = state + 3;

                        if (state == 1)
                        {
                            var task = (node_ch[0].Parent.Tag as dl_task);
                            task.download_state = state;

                            node_ch[0].Parent.Text = CreateTaskNodeText(task);
                            node_ch[0].Parent.ImageIndex = state;
                            node_ch[0].Parent.SelectedImageIndex = state;
                        }
                    }
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " updateChannelDownloadState " + s);
                }
            });

            //更新下载进度
            updateDownloader = new UpdateDownloader(delegate (dl_files file, int time)
            {
                try
                {
                    var progress = this.palDownloadList.Controls.Find("progress_" + file.id, true);
                    if (progress.Length > 0)
                    {
                        DownloadProgress pro = (DownloadProgress)progress[0];
                        //if (file.dl_speed < 1024)
                        //{
                        //    pro.lblSpeed.Text = file.dl_speed.ToString() + " Kb/s";
                        //}
                        //else if (file.dl_speed >= 1024 && file.dl_speed < 1024 * 1024)
                        //{
                        //    pro.lblSpeed.Text = Math.Round(Convert.ToDecimal(file.dl_speed) / 1024, 2).ToString() + "Mb/s";
                        //}
                        //else
                        //{
                        //    pro.lblSpeed.Text = Math.Round(Convert.ToDecimal(file.dl_speed) / 1024 / 1024, 2).ToString() + "Gb/s";
                        //}
                        pro.lblSpeed.Text = PSDFunction.FormatByteSize(Convert.ToDouble(file.dl_speed)) + "/s";
                        pro.lblSpeed.Text += "，已用时 " + time.ToString() + " 秒";
                        pro.lblPercent.Text = "已下载 " + file.dl_progress.ToString() + "%";
                        pro.progressBar1.Value = file.dl_progress;
                    }

                    Application.DoEvents();
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " updateDownloader " + s);
                }
            });

            //完成下载
            finishDownload = new FinishDownload(delegate (dl_files file)
            {
                try
                {
                    var progress = this.palDownloadList.Controls.Find("progress_" + file.id, true);
                    if (progress.Length > 0)
                    {
                        //DownloadProgress pro = (DownloadProgress)progress[0];
                        //if (file.state == 1)
                        //{
                        //pro.pictureBox1.Image = Properties.Resources.success;
                        //pro.lblPercent.Text = "下载完成";

                        palDownloadList.Controls.Remove(progress[0]);
                        if (palDownloadList.Controls.Count == 0)
                        {
                            palDownloadList.BackgroundImage = Properties.Resources.bg;
                        }
                        //}
                        //else
                        //{
                        //    pro.pictureBox1.Image = Properties.Resources.fail;
                        //    pro.lblPercent.Text = "下载失败：" + file.error_log;
                        //    pro.btnRetry.Visible = true;
                        //    pro.btnCancel.Visible = true;
                        //}
                    }

                    Application.DoEvents();
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " finishDownload " + s);

                }
            });

            setDeviceInfo = new SetDeviceInfo(delegate (dl_download_device device)
            {
                try
                {
                    this.psdClient.SetDevice(device);
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                    System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString() + " setDeviceInfo " + s);

                }
            });
            #endregion
        }

        private string CreateTaskNodeText(dl_task task)
        {
            string task_text = task.task_name;

            if (task.download_state == 0)
            {
                task_text += " - 已暂停";
            }
            else if (task.download_state == 1)
            {
                task_text += " - 下载中";
            }
            else if (task.download_state == 2)
            {
                task_text += " - 已结束";
            }

            return task_text;
        }

        private string CreateChannelNodeText(dl_task_channel channel)
        {
            string ch_text = channel.channel_name;

            if (channel.download_state == 0)
            {
                ch_text += " - 已暂停 - ";
            }
            else if (channel.download_state == 1)
            {
                ch_text += " - 下载中 - ";
            }
            else if (channel.download_state == 2)
            {
                ch_text += " - 已结束 - ";
            }

            ch_text += "【已下载成功" + channel.file_count + "个，失败" + channel.error_count + "个】";

            return ch_text;
        }

        private void FrmMain_Shown(object sender, EventArgs e)
        {
            palDownloadList.Controls.Clear();
            tvwTask.Nodes.Clear();

            downloadHelper.OpenPSDClient();

            this.psdClient.SetDevice(downloadHelper.Device);
            this.psdClient.SetDownloadState(downloadHelper.Downloading);
        }

        private void DownloadHelper_OnSetDeviceInfo(dl_download_device device)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(setDeviceInfo, device);
            }
            else
            {
                setDeviceInfo(device);
            }
        }

        private void DownloadHelper_OnCreateTask1(dl_task task, List<dl_task_channel> channels)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(updateTaskTree, task, channels);
            }
            else
            {
                updateTaskTree(task, channels);
            }
        }

        private void DownloadHelper_OnDownloadTaskStateChanged(string id, int state)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(updateTaskDownloadState, id, state);
            }
            else
            {
                updateTaskDownloadState(id, state);
            }
        }

        private void DownloadHelper_OnDownloadChannelStateChanged(string id, int state)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(updateChannelDownloadState, id, state);
            }
            else
            {
                updateChannelDownloadState(id, state);
            }
        }

        /// <summary>
        /// 下载开始事件
        /// </summary>
        private void DownloadHelper_OnStartDownload()
        {
            timerDownload.Enabled = true;
        }

        /// <summary>
        /// 下载停止事件
        /// </summary>
        private void DownloadHelper_OnStopDownload()
        {
            timerDownload.Enabled = false;
        }

        /// <summary>
        /// 下载成功事件
        /// </summary>
        /// <param name="file"></param>
        private void DownloadHelper_OnFileDownloadSuccess(dl_files file)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(finishDownload, file);
            }
            else
            {
                finishDownload(file);
            }
        }

        /// <summary>
        /// 下载失败事件
        /// </summary>
        /// <param name="file"></param>
        private void DownloadHelper_OnFileDownloadFail(dl_files file)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(finishDownload, file);
            }
            else
            {
                finishDownload(file);
            }
        }

        /// <summary>
        /// 更新下载进度事件
        /// </summary>
        /// <param name="file"></param>
        private void DownloadHelper_OnUpdateDownloadProgress(dl_files file, int time)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(updateDownloader, file, time);
            }
            else
            {
                updateDownloader(file, time);
            }
        }

        /// <summary>
        /// 重试下载事件
        /// </summary>
        /// <param name="progress"></param>
        /// <param name="file"></param>
        private void Progress_OnRetry(DownloadProgress progress, dl_files file)
        {
            progress.btnRetry.Visible = false;
            progress.btnCancel.Visible = false;
            progress.pictureBox1.Image = Properties.Resources.download;
            progress.lblSpeed.Text = "0";
            progress.lblPercent.Text = "已下载 0%";

            downloadHelper.CreateDownload(file);
        }


        /// <summary>
        /// 创建下载事件
        /// </summary>
        /// <param name="file"></param>
        private void DownloadHelper_OnCreateDownload(dl_files file)
        {
            CreateDownalderUI(file);
        }

        /// <summary>
        /// 创建一个文件下载控件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private void CreateDownalderUI(dl_files file)
        {
            //更新下载器UI
            var progress = this.palDownloadList.Controls.Find("progress_" + file.id, true);
            DownloadProgress pro = null;
            if (progress.Length > 0)
            {
                pro = (DownloadProgress)progress[0];
            }
            else
            {
                pro = new DownloadProgress();
                pro.Name = "progress_" + file.id;
                pro.Dock = DockStyle.Top;
                pro.lblRoomNum.Text = file.room_num + " - " + file.channel_name;
                pro.lblTime.Text = file.video_start_time.ToString("yyyy-MM-dd HH:mm:ss") + " 至 " + file.video_end_time.ToString("yyyy-MM-dd HH:mm:ss");
                pro.progressBar1.Minimum = 0;
                pro.progressBar1.Maximum = 100;
                pro.FileInfo = file;
                pro.OnRetry += Progress_OnRetry;
                this.palDownloadList.Controls.Add(pro);
                this.palDownloadList.BackgroundImage = null;
            }

            pro.lblSpeed.Text = "0";
            pro.lblPercent.Text = "已下载 0%";
            pro.progressBar1.Value = 0;
            pro.pictureBox1.Image = Properties.Resources.download;

            pro.Refresh();

            Application.DoEvents();
        }

        /// <summary>
        /// 主窗体初次显示，进行初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvwTask_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ShowMenuItem(e.Node.Level);
        }

        private void ShowMenuItem(int type)
        {
            miStartTask.Visible = (type == 0);
            miStopTask.Visible = (type == 0);
            miFinishTask.Visible = (type == 0);
            miStartChannel.Visible = (type == 1);
            miStopChannel.Visible = (type == 1);
            miFinishChannel.Visible = (type == 1);
        }

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (downloadHelper.Running)
            {
                if (MessageBox.Show("是否确定关闭下载助手？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    running = false;

                    downloadHelper.ClosePSDClient();

                    if (downloadHelper.DownloaderList.Count > 0)
                    {
                        lblTaskList.BackColor = Color.Moccasin;
                        lblTaskList.ForeColor = Color.Red;
                        lblTaskList.Text = $"下载任务列表 — 系统将在现有{downloadHelper.DownloaderList.Count}项任务下载完成后自动退出";

                        timerClosing.Enabled = true;

                        e.Cancel = true;
                    }
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        protected override void OnClosed(EventArgs e)
        {
            DaHuaNetClient.Cleanup();
        }

        private void TimerClosing_Tick(object sender, EventArgs e)
        {
            if (!downloadHelper.Downloading && downloadHelper.DownloaderList.Count == 0)
            {
                downloadHelper.LogoutDownloadServer();

                this.Close();
            }
            else
            {
                lblTaskList.Text = $"下载任务列表 — 系统将在现有{downloadHelper.DownloaderList.Count}项任务下载完成后自动退出";
            }
        }

        private void timerDownload_Tick(object sender, EventArgs e)
        {
            if (downloadHelper != null && downloadHelper.Running)
            {
                downloadHelper.DoWork();
            }
        }

        private void miStartTask_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 0)
            {
                var task = tvwTask.SelectedNode.Tag as dl_task;

                downloadHelper.StartDownloadTask(task.id);
            }
        }

        private void miStopTask_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 0)
            {
                var task = tvwTask.SelectedNode.Tag as dl_task;

                downloadHelper.StopDownloadTask(task.id);
            }
        }

        private void miFinishTask_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 0)
            {
                var task = tvwTask.SelectedNode.Tag as dl_task;

                downloadHelper.FinishDownloadTask(task.id);
            }
        }

        private void miStartChannel_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 1)
            {
                var channel = tvwTask.SelectedNode.Tag as dl_task_channel;

                downloadHelper.StartDownloadChannel(channel.id);
            }
        }

        private void miStopChannel_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 1)
            {
                var channel = tvwTask.SelectedNode.Tag as dl_task_channel;

                downloadHelper.StopDownloadChannel(channel.id);
            }
        }

        private void miFinishChannel_Click(object sender, EventArgs e)
        {
            if (tvwTask.SelectedNode != null && tvwTask.SelectedNode.Level == 1)
            {
                var channel = tvwTask.SelectedNode.Tag as dl_task_channel;

                downloadHelper.FinishDownloadChannel(channel.id);
            }
        }
    }
}
